package
{
	import UIComponent.PointSkeleton;
	
	import flash.events.Event;
	import flash.net.FileReference;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	
	import skeletons.CaseSkeleton;
	import skeletons.ConclusionSkeleton;
	import skeletons.DKRelationSkeleton;
	import skeletons.DataSourceSkeleton;
	import skeletons.KConRelationSkeleton;
	import skeletons.KnowledgeSkeleton;
	
	import sprites.CaseSprite;
	import sprites.ConclustionSprite;
	import sprites.DKRelationSprite;
	import sprites.DataSourceSprite;
	import sprites.KConRelationSprite;
	import sprites.KnowledgeSprite;

	public class Project
	{
		private var projectID:int=new int();
		var name:String;
		var discription:String;
		var caseList:ArrayList;
		var knowledgeList:ArrayList;
		var conclusionList:ArrayList;
		
		private var DKRelationList:ArrayList;
		private var KConRelationList:ArrayList;
		private var canvas:MyCanvas;
		
		
		//remote service
		static private var baseURL:String = "http://127.0.0.1";
		private var readyConnect:Number=0;
		
		//static
		static private var DEFAULT_CASE_NAME:String="Untitle Case";
		static private var DEFAULT_DATA_NAME:String="Untitle Datasource";
		static private var DEFAULT_KNOWLEDGE_NAME:String="Untitle Knowledge";
		static private var DEFAULT_CONCLUSION_NAME:String="Untitle Conclusion";
		static private var DEFAULT_DISCRIPTION:String="Write discription here";
		
		public function Project(_canvas:MyCanvas,_PID:int)
		{
			canvas=_canvas;
			//just for test
			projectID=_PID;
			LoadProject("null");
		}
		
		public function LoadProject(_name:String):Boolean
		{
			caseList=new ArrayList();
			knowledgeList=new ArrayList();
			conclusionList=new ArrayList();
			DKRelationList = new ArrayList();
			KConRelationList= new ArrayList();
	
			loadCase(projectID);
			loadKnowledge(projectID);
			loadConclusion(projectID);
			
			return true;
		}
		
		public function addCase(_CID:int,_name:String, _discription:String):void
		{
			var tempCase:CaseSkeleton=new CaseSkeleton();
			tempCase.setCID(_CID);
			tempCase.setName(_name);
			tempCase.setDiscription(_discription);
			if(caseList==null)
			{
				caseList=new ArrayList();
			}
			caseList.addItem(tempCase);
			
			if(canvas!=null)
			{
				tempCase.setSprite(new CaseSprite(tempCase,canvas));
				canvas.addChild(tempCase.getSprite());
			}
		}
		
		public function addData(_parent:CaseSkeleton,_DID:int, _name:String, _discription:String):void
		{
			var tempData:DataSourceSkeleton=new DataSourceSkeleton(_parent);
			tempData.setDID(_DID);
			tempData.setName(_name);
			tempData.setDiscription(_discription);
			if(_parent.getDataSourceList()==null)
			{
				_parent.setDataSourceList(new ArrayList());
			}
			_parent.getDataSourceList().addItem(tempData);
			
			if(canvas!=null)
			{
				tempData.setSprite(new DataSourceSprite(tempData,this.canvas));
				canvas.addChild(tempData.getSprite());
			}
			
		}
		
		public function addKnowledge(_KID:int,_name:String, _discription:String):void
		{
			var tempKnow:KnowledgeSkeleton=new KnowledgeSkeleton();
			tempKnow.setKID(_KID);
			tempKnow.setName(_name);
			tempKnow.setDiscription(_discription);
			if(knowledgeList==null)
			{
				knowledgeList=new ArrayList();	
			}
			knowledgeList.addItem(tempKnow);
			
			if(canvas!=null)
			{	
				tempKnow.setSprite(new KnowledgeSprite(tempKnow,this.canvas));
				canvas.addChild(tempKnow.getSprite());
			}
		}
		
		public function addConclusion(_ConID:int,_name:String, _discription:String):void
		{
			var tempCon:ConclusionSkeleton=new ConclusionSkeleton();
			tempCon.setConID(_ConID);
			tempCon.setName(_name);
			tempCon.setDiscription(_discription);
			if(conclusionList==null)
			{
				conclusionList=new ArrayList();
			}
			conclusionList.addItem(tempCon);
			
			if(canvas!=null)
			{	
				tempCon.setSprite(new ConclustionSprite(tempCon,canvas));
				canvas.addChild(tempCon.getSprite());
			}
		}
		
		public function addDKRelation(_dataSource:DataSourceSkeleton, _knowledge:KnowledgeSkeleton, _type:int):DKRelationSkeleton
		{	
			//judge whether has existed
			var i:Number=0;
			var DKList:ArrayList=_dataSource.getDKList();
			if(DKList!=null)
			{
				for(i=0; i<DKList.length; i++)
				{
					if( (KnowledgeSkeleton)((DKRelationSkeleton)(DKList.getItemAt(i)).getToPointSkeleton()) == _knowledge )
					{
						return null;
					}
				}
			}
			//create DK Relation
			var tempDK:DKRelationSkeleton=new DKRelationSkeleton();
			getDKRelationList().addItem(tempDK);
			tempDK.setFromPointSkeleton(_dataSource);
			tempDK.setToPointSkeleton(_knowledge);
			tempDK.setType(_type);
			
			if(_dataSource.getDKList()==null)
			{
				_dataSource.setDKList(new ArrayList());
			}
			_dataSource.getDKList().addItem(tempDK);
			
			if(_knowledge.getDKList()==null)
			{
				_knowledge.setDKList(new ArrayList());
			}
			_knowledge.getDKList().addItem(tempDK);
			
			if(canvas!=null)
			{
				tempDK.setSprite(new DKRelationSprite(tempDK,canvas));
			}
			
			return tempDK;
		}
		
		public function addKConRelation(_knowledge:KnowledgeSkeleton, _conclusion:ConclusionSkeleton, _type:int):KConRelationSkeleton
		{
			//judge whether has existed
			var i:Number=0;
			var KConList:ArrayList= _conclusion.getKConList();
			if(KConList!=null)
			{
				for(i=0; i<KConList.length; i++)
				{
					if( (KnowledgeSkeleton)((KConRelationSkeleton)(KConList.getItemAt(i)).getFromPointSkeleton()) == _knowledge )
					{
						return null;
					}
				}
			}
			
			var tempKCon:KConRelationSkeleton=new KConRelationSkeleton();
			getKConRelationList().addItem(tempKCon);
			tempKCon.setFromPointSkeleton(_knowledge);
			tempKCon.setToPointSkeleton(_conclusion);
			tempKCon.setType(_type);
			
			if(_knowledge.getKConList()==null)
			{
				_knowledge.setKConList(new ArrayList());
			}
			_knowledge.getKConList().addItem(tempKCon);
			
			if(_conclusion.getKConList()==null)
			{
				_conclusion.setKConList(new ArrayList());
			}
			_conclusion.getKConList().addItem(tempKCon);
			
			if(canvas!=null)
			{
				tempKCon.setSprite(new KConRelationSprite(tempKCon,canvas));
			}
			
			return tempKCon;
		}
		
		//remove case sender
		public function removeCase(_case:CaseSkeleton):void
		{
			var CID:int = _case.getCID();
			
			var removeCaseService:HTTPService = new HTTPService();
			removeCaseService.url =baseURL+"/removeCaseFromCID.php?CID="+CID+"&rand="+Math.random();
			removeCaseService.addEventListener(ResultEvent.RESULT,removeCaseAsync);
			removeCaseService.addEventListener(FaultEvent.FAULT,onfault);
			removeCaseService.useProxy=false;
			removeCaseService.send();
		}
		
		//remove case async
		private function removeCaseAsync(evt:ResultEvent):void
		{
			if(evt.result.CID == null)
				return;
			
			var curCase:CaseSkeleton = getCaseFromCID((int)(evt.result.CID));
			
			if(curCase.getDataSourceList()!=null)
			{
				var i:int;
				for(i=0;i<curCase.getDataSourceList().length;i++)
				{
					parentRemoveData((DataSourceSkeleton)(curCase.getDataSourceList().getItemAt(i)));
				}
			}
			curCase.getSprite().remove();
			this.caseList.removeItem(curCase);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		
		//case remove datasource
		private function parentRemoveData(_data:DataSourceSkeleton):void
		{
			if(_data==null){
				return;
			}
			if(_data.getDKList()!=null)
			{
				var i:int;
				for(i=0;i<_data.getDKList().length;i++)
				{
					var curDK:DKRelationSkeleton=(DKRelationSkeleton)(_data.getDKList().getItemAt(i));
					var toKnowledge:KnowledgeSkeleton=(KnowledgeSkeleton)(curDK.getToPointSkeleton());
					toKnowledge.getDKList().removeItem(curDK);
					DKRelationList.removeItem(curDK);
				}
				_data.getDKList().removeAll();
			}
			_data.getSprite().remove();
		}
		//remove dataSource sender
		public function removeData(_data:DataSourceSkeleton):void
		{
			var DID:int = _data.getDID();
			
			var removeDataSourceService:HTTPService = new HTTPService();
			removeDataSourceService.url =baseURL+"/removeDataSourceFromDID.php?DID="+DID+"&rand="+Math.random();
			removeDataSourceService.addEventListener(ResultEvent.RESULT,removeDataSourceAsync);
			removeDataSourceService.addEventListener(FaultEvent.FAULT,onfault);
			removeDataSourceService.useProxy=false;
			removeDataSourceService.send();
		}
		//remove dataSource async
		private function removeDataSourceAsync(evt:ResultEvent):void
		{
			if(evt.result.DID == null)
				return;
			
			var curData:DataSourceSkeleton = getDataFromDID((int)(evt.result.DID));
			if(curData==null){
				return;
			}
			parentRemoveData(curData);
			curData.getPcase().getDataSourceList().removeItem(curData);
			
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		//remove knowledge sender
		public function removeKnowledge(_know:KnowledgeSkeleton):void
		{
			var KID:int = _know.getKID();
			
			var removeKnowledgeService:HTTPService = new HTTPService();
			removeKnowledgeService.url =baseURL+"/removeKnowledgeFromKID.php?KID="+KID+"&rand="+Math.random();
			removeKnowledgeService.addEventListener(ResultEvent.RESULT,removeKnowledgeAsync);
			removeKnowledgeService.addEventListener(FaultEvent.FAULT,onfault);
			removeKnowledgeService.useProxy=false;
			removeKnowledgeService.send();
			
		}
		//remove knowledge async
		private function removeKnowledgeAsync(evt:ResultEvent):void
		{
			if(evt.result.KID==null)
				return;
			
			var curKnow:KnowledgeSkeleton = getKnowledgeFromKID((int)(evt.result.KID));
			//delete DKList
			var i:int=0;
			if(curKnow.getDKList()!=null)
			{
				for(i=0;i<curKnow.getDKList().length;i++)
				{
					var curDK:DKRelationSkeleton=(DKRelationSkeleton)(curKnow.getDKList().getItemAt(i));
					var toData:DataSourceSkeleton=(DataSourceSkeleton)(curDK.getFromPointSkeleton());
					toData.getDKList().removeItem(curDK);
					getDKRelationList().removeItem(curDK);
				}
				curKnow.getDKList().removeAll();
			}
			//delete KConList
			if(curKnow.getKConList()!=null)
			{
				for(i=0;i<curKnow.getKConList().length;i++)
				{
					var curKCon:KConRelationSkeleton=(KConRelationSkeleton)(curKnow.getKConList().getItemAt(i));
					var toCon:ConclusionSkeleton=(ConclusionSkeleton)(curKCon.getToPointSkeleton());
					toCon.getKConList().removeItem(curKCon);
					getKConRelationList().removeItem(curKCon);
				}
				curKnow.getKConList().removeAll();
			}
			curKnow.getSprite().remove();
			this.knowledgeList.removeItem(curKnow);
			
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		//remove conclusion sender
		public function removeConclusion(_con:ConclusionSkeleton):void
		{
			var ConID:int = _con.getConID();
			
			var removeConclusionService:HTTPService = new HTTPService();
			removeConclusionService.url =baseURL+"/removeConclusionFromConID.php?ConID="+ConID+"&rand="+Math.random();
			removeConclusionService.addEventListener(ResultEvent.RESULT,removeConclusionAsync);
			removeConclusionService.addEventListener(FaultEvent.FAULT,onfault);
			removeConclusionService.useProxy=false;
			removeConclusionService.send();
		}
		//remove conclusion async
		private function removeConclusionAsync(evt:ResultEvent):void
		{
			if(evt.result.ConID==null)
				return;
			
			var curCon:ConclusionSkeleton = getConclusionFromConID( (int)(evt.result.ConID));
			
			if(curCon.getKConList()!=null)
			{
				var i:int;
				for(i=0;i<curCon.getKConList().length;i++)
				{
					var curKCon:KConRelationSkeleton=(KConRelationSkeleton)(curCon.getKConList().getItemAt(i));
					var toKnow:KnowledgeSkeleton=(KnowledgeSkeleton)(curKCon.getFromPointSkeleton());
					toKnow.getKConList().removeItem(curKCon);
					getKConRelationList().removeItem(curKCon);
				}
				curCon.getKConList().removeAll();
			}
			
			curCon.getSprite().remove();
			this.conclusionList.removeItem(curCon);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			
		}
		//remove DK Relation sender
		public function removeDK(_DK:DKRelationSkeleton, _caller:int):void //caller 0 -datasource 1 -knowledge
		{
			var DID:int = (DataSourceSkeleton)(_DK.getFromPointSkeleton()).getDID();
			var KID:int = (KnowledgeSkeleton)(_DK.getToPointSkeleton()).getKID();
			
			var removeDKService:HTTPService = new HTTPService();
			removeDKService.url =baseURL+"/removeDKRelationFromDIDandKID.php?DID="+DID+"&KID="+KID+"&caller="+_caller+"&rand="+Math.random();
			removeDKService.addEventListener(ResultEvent.RESULT,removeDKAsync);
			removeDKService.addEventListener(FaultEvent.FAULT,onfault);
			removeDKService.useProxy=false;
			removeDKService.send();		
		}
		//remove DK Relation async
		private function removeDKAsync(evt:ResultEvent):void
		{
			if(evt.result.Result==null || evt.result.Result.DID==null || evt.result.Result.KID==null)
				return;
			
			var curData:DataSourceSkeleton = getDataFromDID((int)(evt.result.Result.DID));
			var curKnow:KnowledgeSkeleton = getKnowledgeFromKID((int)(evt.result.Result.KID));
			var curDK:DKRelationSkeleton = getDKRelation(curData,curKnow);
			if(curDK==null)
			{
				return;
			}
			
			curData.getDKList().removeItem(curDK);
			curKnow.getDKList().removeItem(curDK);
			getDKRelationList().removeItem(curDK);
			
			if(canvas!=null)
			{			
				canvas.invalidateDisplayList();
			}
		}
		//get DK Relation from references of DataSource and Knowledge
		private function getDKRelation(_dataSource:DataSourceSkeleton, _knowledge:KnowledgeSkeleton):DKRelationSkeleton
		{
			var DKList:ArrayList=_dataSource.getDKList();
			if(DKList==null)
			{
				return null;
			}
			var i:Number=0;
			for(i=0; i<DKList.length; i++)
			{
				if( _knowledge == (KnowledgeSkeleton)((DKRelationSkeleton)(DKList.getItemAt(i)).getToPointSkeleton()))
				{
					return (DKRelationSkeleton)(DKList.getItemAt(i));
				}
			}
			return null;
		}
		//get KCon Relation from references of Knowledge and Conclusion
		private function getKConRelation(_knowledge:KnowledgeSkeleton, _conclusion:ConclusionSkeleton):KConRelationSkeleton
		{
			var KConList:ArrayList = _knowledge.getKConList();
			if(KConList ==null)
			{
				return null;
			}
			var i:int=0;
			for(i=0; i<KConList.length; i++)
			{
				if( _conclusion == (ConclusionSkeleton)((KConRelationSkeleton)(KConList.getItemAt(i)).getToPointSkeleton()) )
				{
					return (KConRelationSkeleton)(KConList.getItemAt(i));
				}
			}
			return null;
		}
		//remove KCon Relation sender
		public function removeKCon(_KCon:KConRelationSkeleton, _caller:int):void
		{
			var KID:int = (KnowledgeSkeleton)(_KCon.getFromPointSkeleton()).getKID();
			var ConID:int = (ConclusionSkeleton)(_KCon.getToPointSkeleton()).getConID();
			
			var removeKConService:HTTPService = new HTTPService();
			removeKConService.url =baseURL+"/removeKConRelationFromKIDandConID.php?ConID="+ConID+"&KID="+KID+"&caller="+_caller+"&rand="+Math.random();
			removeKConService.addEventListener(ResultEvent.RESULT,removeKConAsync);
			removeKConService.addEventListener(FaultEvent.FAULT,onfault);
			removeKConService.useProxy=false;
			removeKConService.send();
			
		}
		//remove KCon Relation async
		private function removeKConAsync(evt:ResultEvent):void
		{
			if( evt.result.Result==null || evt.result.Result.KID==null || evt.result.Result.ConID==null || evt.result.Result.caller==null)
				return;
			
			var curKnow:KnowledgeSkeleton = getKnowledgeFromKID((int)(evt.result.Result.KID));
			var curCon:ConclusionSkeleton = getConclusionFromConID((int)(evt.result.Result.ConID));
			var KCon:KConRelationSkeleton = getKConRelation(curKnow,curCon);
			if(KCon ==null)
			{
				return;
			}
			
			curKnow.getKConList().removeItem(KCon);
			curCon.getKConList().removeItem(KCon);
			getKConRelationList().removeItem(KCon);
			
			if(canvas !=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		//get case sender
		public function loadCase(PID:int):void
		{
			var loadCaseService:HTTPService = new HTTPService();
			loadCaseService.url =baseURL+"/getCasesFromProjectID.php?PID="+PID+"&rand="+Math.random();
			loadCaseService.addEventListener(ResultEvent.RESULT,loadCaseAsync);
			loadCaseService.addEventListener(FaultEvent.FAULT,onfault);
			loadCaseService.useProxy=false;
			loadCaseService.send();
			return;
		} 
		//get case async
		private function loadCaseAsync(evt:ResultEvent):void
		{
			if(evt.result.bcases==null || evt.result.bcases.bcase ==null)
				return;
			
			if(evt.result.bcases.bcase is ArrayCollection )
			{
				var bcaseList:ArrayCollection= (ArrayCollection)(evt.result.bcases.bcase);
				var i:Number=0;
				for(i=0;i<bcaseList.length;i++)
				{
					addCase((int)(bcaseList.getItemAt(i).CID),
						(String)(bcaseList.getItemAt(i).name), 
						(String)(bcaseList.getItemAt(i).discription));
				}
			}
			else
			{
				addCase((int)(evt.result.bcases.bcase.CID),
					(String)(evt.result.bcases.bcase.name),
					(String)(evt.result.bcases.bcase.discription));
			}
			loadDataSource();
			return;
		}
		//get DataSource sender
		public function loadDataSource():void
		{
			var loadDataSourceService:HTTPService=new HTTPService();
			loadDataSourceService.addEventListener(ResultEvent.RESULT,loadDatasourceAsync);
			loadDataSourceService.addEventListener(FaultEvent.FAULT,onfault);
			loadDataSourceService.useProxy=false;
			var i:Number=0;
			for(i=0;i<caseList.length;i++)
			{
				var CID:int = (CaseSkeleton)(caseList.getItemAt(i)).getCID();
				loadDataSourceService.url = baseURL+"/getDataSourceFromCID.php?CID="+CID+"&rand="+Math.random();
				loadDataSourceService.send();
			}
		}
		//get Knowledge sender
		public function loadKnowledge(PID:int):void
		{
			var loadKnowledgeService:HTTPService = new HTTPService();
			loadKnowledgeService.url =baseURL+"/getKnowledgeFromPID.php?PID="+PID+"&rand="+Math.random();
			loadKnowledgeService.addEventListener(ResultEvent.RESULT,loadKnowledgeAsync);
			loadKnowledgeService.addEventListener(FaultEvent.FAULT,onfault);
			loadKnowledgeService.useProxy=false;
			loadKnowledgeService.send();
			return;
		}
		//get Knowledge async
		private function loadKnowledgeAsync(evt:ResultEvent):void
		{
			if(evt.result.knowledges==null || evt.result.knowledges.knowledge ==null)
				return;
			
			if(evt.result.knowledges.knowledge is ArrayCollection )
			{
				var knowledgeList:ArrayCollection= (ArrayCollection)(evt.result.knowledges.knowledge);
				var i:Number=0;
				for(i=0;i<knowledgeList.length;i++)
				{
					addKnowledge((int)(knowledgeList.getItemAt(i).KID),
						(String)(knowledgeList.getItemAt(i).name), 
						(String)(knowledgeList.getItemAt(i).discription));
				}
			}
			else
			{
				addKnowledge((int)(evt.result.knowledges.knowledge.KID),
					(String)(evt.result.knowledges.knowledge.name),
					(String)(evt.result.knowledges.knowledge.discription));
			}
			decideToLoadRelation();
			
			return;
		}
		//get Datasource async
		private function loadDatasourceAsync(evt:ResultEvent):void
		{
			if(evt.result.datasources==null || evt.result.datasources.datasource ==null)
				return;
			
			if(evt.result.datasources.datasource is ArrayCollection)
			{
				var dataList:ArrayCollection= (ArrayCollection)(evt.result.datasources.datasource);
				//get CID
				var CID:int = (int)(dataList.getItemAt(0).CID);
				//get Case
				var curCase:CaseSkeleton=getCaseFromCID(CID);
				
				if(curCase==null)		//not found
				{
					return;
				}
				//add datasource
				var i:Number=0;
				for(i=0;i<dataList.length;i++)
				{
					this.addData(curCase,(int)(dataList.getItemAt(i).DID) ,(String)(dataList.getItemAt(i).name), (String)(dataList.getItemAt(i).discription));
				}
			}
			else
			{
				var CID:int = evt.result.datasources.datasource.CID;
				var curCase:CaseSkeleton=getCaseFromCID(CID);
				addData(curCase, (int)(evt.result.datasources.datasource.DID),(String)(evt.result.datasources.datasource.name), (String)(evt.result.datasources.datasource.discription));
			}
			decideToLoadRelation();
		}
		//get Conclusion sender
		public function loadConclusion(PID:int):void
		{
			var loadConclusionService:HTTPService = new HTTPService();
			loadConclusionService.url =baseURL+"/getConclusionFromPID.php?PID="+PID+"&rand="+Math.random();
			loadConclusionService.addEventListener(ResultEvent.RESULT,loadConclusionAsync);
			loadConclusionService.addEventListener(FaultEvent.FAULT,onfault);
			loadConclusionService.useProxy=false;
			loadConclusionService.send();
			return;
		}
		//get Conclusion async
		private function loadConclusionAsync(evt:ResultEvent):void
		{
			if(evt.result.conclusions==null || evt.result.conclusions.conclusion ==null)
				return;
			
			if(evt.result.conclusions.conclusion is ArrayCollection )
			{
				var conclusionList:ArrayCollection= (ArrayCollection)(evt.result.conclusions.conclusion);
				var i:Number=0;
				for(i=0;i<conclusionList.length;i++)
				{
					addConclusion((int)(conclusionList.getItemAt(i).ConID),
						(String)(conclusionList.getItemAt(i).name), 
						(String)(conclusionList.getItemAt(i).discription));
				}
			}
			else
			{
				addConclusion((int)(evt.result.conclusions.conclusion.ConID),
					(String)(evt.result.conclusions.conclusion.name),
					(String)(evt.result.conclusions.conclusion.discription));
			}
			
			decideToLoadRelation();
			return;
		}
		//get DKRelations and KConRelations sender
		public function loadRelation():void
		{
			var loadDKRelationService:HTTPService=new HTTPService();
			loadDKRelationService.addEventListener(ResultEvent.RESULT,loadDKRelationAsync);
			loadDKRelationService.addEventListener(FaultEvent.FAULT,onfault);
			loadDKRelationService.useProxy=false;
			
			var loadKConRelationService:HTTPService=new HTTPService();
			loadKConRelationService.addEventListener(ResultEvent.RESULT,loadKConRelationAsync);
			loadKConRelationService.addEventListener(FaultEvent.FAULT,onfault);
			loadKConRelationService.useProxy=false;
			var i:Number=0;
			for(i=0;i<knowledgeList.length;i++)
			{
				var KID:int = (KnowledgeSkeleton)(knowledgeList.getItemAt(i)).getKID();
				
				loadDKRelationService.url = baseURL+"/getDKRelationFromKID.php?KID="+KID+"&rand="+Math.random();
				loadDKRelationService.send();
				
				loadKConRelationService.url = baseURL+"/getKConRelationFromKID.php?KID="+KID+"&rand="+Math.random();
				loadKConRelationService.send();
			}
		}
		
		//load DK Relation async
		private function loadDKRelationAsync(evt:ResultEvent):void
		{
			if(evt.result.DKRelations==null || evt.result.DKRelations.DKRelation==null)
				return;
			
			if(evt.result.DKRelations.DKRelation is ArrayCollection)
			{
				var DKList:ArrayCollection = (ArrayCollection)(evt.result.DKRelations.DKRelation);
				//get KID
				var KID:int = (int)(DKList.getItemAt(0).KID);
				var curKnow:KnowledgeSkeleton = getKnowledgeFromKID(KID);
				if(curKnow ==null)
				{
					return;
				}
				var i:Number=0;
				for(i=0; i<DKList.length; i++)
				{
					var DID:int = (int)(DKList.getItemAt(i).DID);
					var type:int = (int)(DKList.getItemAt(i).type);
					var curData:DataSourceSkeleton = getDataFromDID(DID);
					if(curData==null)
					{
						continue;
					}
					var tempDK:DKRelationSkeleton = addDKRelation(curData,curKnow,type);
				}
			}
			else
			{
				//get KID
				var KID:int =(int)(evt.result.DKRelations.DKRelation.KID);
				var DID:int =(int)(evt.result.DKRelations.DKRelation.DID);
				var type:int =(int)(evt.result.DKRelations.DKRelation.type);
				
				var curData:DataSourceSkeleton = getDataFromDID(DID);
				var curKnow:KnowledgeSkeleton = getKnowledgeFromKID(KID);
				
				if(curData==null || curKnow==null)
				{
					return;
				}
				var tempDK:DKRelationSkeleton = addDKRelation(curData,curKnow,type);
			}
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		
		//get KCon Relation async
		private function loadKConRelationAsync(evt:ResultEvent):void
		{
			if(evt.result.KConRelations==null || evt.result.KConRelations.KConRelation==null)
				return;
			
			if(evt.result.KConRelations.KConRelation is ArrayCollection)
			{
				var KConList:ArrayCollection = (ArrayCollection)(evt.result.KConRelations.KConRelation);
				//get KID
				var KID:int = (int)(KConList.getItemAt(0).KID);
				var curKnow:KnowledgeSkeleton = getKnowledgeFromKID(KID);
				if(curKnow ==null)
				{
					return;
				}
				var i:Number=0;
				for(i=0; i<KConList.length; i++)
				{
					var ConID:int = (int)(KConList.getItemAt(i).ConID);
					var type:int = (int)(KConList.getItemAt(i).type);
					var curCon:ConclusionSkeleton = getConclusionFromConID(ConID);
					if(curCon==null)
					{
						continue;
					}
					var tempKCon:KConRelationSkeleton=addKConRelation(curKnow,curCon,type);
					if(canvas!=null)
					{
						canvas.invalidateDisplayList();
					}
				}
			}
			else
			{
				//get KID
				var KID:int =(int)(evt.result.KConRelations.KConRelation.KID);
				var ConID:int =(int)(evt.result.KConRelations.KConRelation.ConID);
				var type:int =(int)(evt.result.KConRelations.KConRelation.type);
				
				var curCon:ConclusionSkeleton = getConclusionFromConID(ConID);
				var curKnow:KnowledgeSkeleton = getKnowledgeFromKID(KID);
				
				if(curCon==null || curKnow==null)
				{
					return;
				}
				var tempKCon:KConRelationSkeleton=addKConRelation(curKnow,curCon,type);
				
				if(canvas!=null)
				{
					canvas.invalidateDisplayList();
				}
			}
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
		}
		//on fault
		private function onfault(evt:FaultEvent):void
		{
			trace(evt.toString());
		}	
		//get Case from CID
		private function getCaseFromCID(_CID:int):CaseSkeleton
		{
			var i:Number=0;
			for(i=0;i<caseList.length;i++)
			{
				if((CaseSkeleton)(caseList.getItemAt(i)).getCID() == _CID)
				{
					return (CaseSkeleton)(caseList.getItemAt(i));
				}
			}
			return null;
		}
		//get Knowledge from KID
		private function getKnowledgeFromKID(_KID:int):KnowledgeSkeleton
		{
			var i:Number=0;
			for(i=0; i<knowledgeList.length ;i++)
			{
				if(_KID == (KnowledgeSkeleton)(knowledgeList.getItemAt(i)).getKID())
				{
					return (KnowledgeSkeleton)(knowledgeList.getItemAt(i));
				}
			}
			return null;
		}
		//get Conclusion from ConID
		private function getConclusionFromConID(_ConID:int):ConclusionSkeleton
		{
			var i:Number=0;
			for(i=0; i<conclusionList.length ;i++)
			{
				if(_ConID == (ConclusionSkeleton)(conclusionList.getItemAt(i)).getConID())
				{
					return (ConclusionSkeleton)(conclusionList.getItemAt(i));
				}
			}
			return null;
		}
		//get DataSource from DID
		private function getDataFromDID(_DID:int):DataSourceSkeleton
		{
			var i:Number=0;
			var j:Number=0;
			for(i=0; i<caseList.length ;i++)
			{
				var dataList:ArrayList= (CaseSkeleton)(caseList.getItemAt(i)).getDataSourceList();
				if(dataList==null)
					continue;
				for(j=0; j<dataList.length; j++)
				{
					if(_DID == (DataSourceSkeleton)(dataList.getItemAt(j)).getDID())
					{
						return (DataSourceSkeleton)(dataList.getItemAt(j));
					}
				}
			}
			return null;
		}
		//decide if to load relation
		private function decideToLoadRelation():void
		{
			readyConnect++;
			if(readyConnect==3)
			{
				if(canvas!=null)
				{
					canvas.includeInLayout;
				}
				loadRelation();
			}
		}
		//add case sender
		public function sendAddCase(_PID:int):void
		{
			var addCaseService:HTTPService = new HTTPService()
			addCaseService.url =baseURL+"/addCase.php?PID="+_PID+"&name="+DEFAULT_CASE_NAME+"&rand="+Math.random();
			addCaseService.addEventListener(ResultEvent.RESULT,addCaseAsync);
			addCaseService.addEventListener(FaultEvent.FAULT,onfault);
			addCaseService.useProxy=false;
			addCaseService.send();
			return;
		}
		//add case async
		private function addCaseAsync(evt:ResultEvent):void
		{
			if(evt.result.CID == null)
				return;
			
			var CID:int = (int)(evt.result.CID);
			addCase(CID,DEFAULT_CASE_NAME,DEFAULT_DISCRIPTION);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
		}
		//add data sender
		public function sendAddData(_CID:int):void
		{
			var addDataService:HTTPService = new HTTPService();
			addDataService.url =baseURL+"/addDataSource.php?CID="+_CID+"&name="+DEFAULT_DATA_NAME+"&rand="+Math.random();
			addDataService.addEventListener(ResultEvent.RESULT,addDataAsync);
			addDataService.addEventListener(FaultEvent.FAULT,onfault);
			addDataService.useProxy=false;
			addDataService.send();
			return;
		}
		//add data async
		private function addDataAsync(evt:ResultEvent):void
		{
			if(evt.result.Result.CID == null || evt.result.Result.DID == null)
				return;
			
			var CID:int = (int)(evt.result.Result.CID);
			var DID:int = (int)(evt.result.Result.DID);
			var curCase:CaseSkeleton = getCaseFromCID(CID);
			
			addData(curCase,DID,DEFAULT_DATA_NAME,DEFAULT_DISCRIPTION);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
		}
		//add Knowledge sender
		public function sendAddKnowledge(_PID:int):void
		{
			var addKnowledgeService:HTTPService = new HTTPService();
			addKnowledgeService.url =baseURL+"/addKnowledge.php?PID="+_PID+"&name="+DEFAULT_KNOWLEDGE_NAME+"&rand="+Math.random();
			addKnowledgeService.addEventListener(ResultEvent.RESULT,addKnowledgeAsync);
			addKnowledgeService.addEventListener(FaultEvent.FAULT,onfault);
			addKnowledgeService.useProxy=false;
			addKnowledgeService.send();
			return;
		}
		//add Knowledge async
		private function addKnowledgeAsync(evt:ResultEvent):void
		{
			if(evt.result.KID == null)
				return;
			
			var KID:int = (int)(evt.result.KID);
			addKnowledge(KID,DEFAULT_KNOWLEDGE_NAME,DEFAULT_DISCRIPTION);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
		}
		//add Conclusion sender
		public function sendAddConclusion(_PID:int):void
		{
			var addConclusionService:HTTPService = new HTTPService();
			addConclusionService.url =baseURL+"/addConclusion.php?PID="+_PID+"&name="+DEFAULT_CONCLUSION_NAME+"&rand="+Math.random();
			addConclusionService.addEventListener(ResultEvent.RESULT,addConclusionAsync);
			addConclusionService.addEventListener(FaultEvent.FAULT,onfault);
			addConclusionService.useProxy=false;
			addConclusionService.send();
			return;
		}
		//add Conclusion async
		private function addConclusionAsync(evt:ResultEvent):void
		{
			if(evt.result.ConID == null)
				return;
			
			var ConID:int = (int)(evt.result.ConID);
			addConclusion(ConID,DEFAULT_CONCLUSION_NAME,DEFAULT_DISCRIPTION);
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
		}
		//add DK Relation sender
		public function sendAddDKRelation(_DID:int,_KID:int,_type:int):void
		{
			var addDKRelationService:HTTPService = new HTTPService();
			addDKRelationService.url =baseURL+"/addDKRelation.php?DID="+_DID+"&KID="+_KID+"&type="+_type+"&rand="+Math.random();
			addDKRelationService.addEventListener(ResultEvent.RESULT,addDKRelationAsync);
			addDKRelationService.addEventListener(FaultEvent.FAULT,onfault);
			addDKRelationService.useProxy=false;
			addDKRelationService.send();
		}
		//add DK Realion async
		private function addDKRelationAsync(evt:ResultEvent):void
		{
			if(evt.result.Result==null || evt.result.Result.DID==null)
				return;
			
			var curData:DataSourceSkeleton = getDataFromDID( (int)(evt.result.Result.DID));
			var curKnow:KnowledgeSkeleton = getKnowledgeFromKID( (int)(evt.result.Result.KID));
			
			var tempDK:DKRelationSkeleton = addDKRelation(curData,curKnow, (int)(evt.result.Result.type));
			
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
			
		}
		//add KCon Relation sender
		public function sendKConRelation(_KID:int,_ConID:int,_type:int):void
		{
			var addKConRelationService:HTTPService = new HTTPService();
			addKConRelationService.url =baseURL+"/addKConRelation.php?KID="+_KID+"&ConID="+_ConID+"&type="+_type+"&rand="+Math.random();
			//trace(addConclusionService.url);
			addKConRelationService.addEventListener(ResultEvent.RESULT,addKConRelationAsync);
			addKConRelationService.addEventListener(FaultEvent.FAULT,onfault);
			addKConRelationService.useProxy=false;
			addKConRelationService.send();
		}
		//add KCon Relation async
		private function addKConRelationAsync(evt:ResultEvent):void
		{
			if(evt.result.Result==null || evt.result.Result.KID==null)
				return;
			
			var curKnow:KnowledgeSkeleton = getKnowledgeFromKID( (int)(evt.result.Result.KID));
			var curCon:ConclusionSkeleton = getConclusionFromConID( (int)(evt.result.Result.ConID));
			
			var tempKCon:KConRelationSkeleton = addKConRelation(curKnow,curCon ,(int)(evt.result.Result.type));
			
			if(canvas!=null)
			{
				canvas.invalidateDisplayList();
			}
			return;
			
		}
		//modify name sender
		public function modifyName(_point:PointSkeleton, _name:String, _type:int):void  //_type 0-case 1-datasource 2-knowledge 3-conclusion
		{
			var ID:int=0;
			var modifyNameService:HTTPService =new HTTPService();
			modifyNameService.addEventListener(ResultEvent.RESULT,modifyNameAsync);
			modifyNameService.addEventListener(FaultEvent.FAULT,onfault);
			modifyNameService.useProxy=false;
			
			switch(_type)
			{
				case 0:
					ID=(CaseSkeleton)(_point).getCID();
					modifyNameService.url = baseURL + "/modifyCaseName.php?CID="+ID+"&name="+_name+"&type="+_type+"&rand="+Math.random();
					break;
				case 1:
					ID=(DataSourceSkeleton)(_point).getDID();
					modifyNameService.url = baseURL + "/modifyDataSourceName.php?DID="+ID+"&name="+_name+"&type="+_type+"&rand="+Math.random();
					break;
				case 2:
					ID=(KnowledgeSkeleton)(_point).getKID();
					modifyNameService.url = baseURL + "/modifyKnowledgeName.php?KID="+ID+"&name="+_name+"&type="+_type+"&rand="+Math.random();
					break;
				case 3:
					ID=(ConclusionSkeleton)(_point).getConID();
					modifyNameService.url = baseURL + "/modifyConclusionName.php?ConID="+ID+"&name="+_name+"&type="+_type+"&rand="+Math.random();
					break;
			}
			modifyNameService.send();
		}
		//modify discription sender
		public function modifyDiscription(_point:PointSkeleton, _discription:String, _type:int):void  //_type 0-case 1-datasource 2-knowledge 3-conclusion
		{
			var ID:int=0;
			var modifyDiscriptionService:HTTPService = new HTTPService();
			modifyDiscriptionService.addEventListener(ResultEvent.RESULT, modifyDiscriptionAsync);
			modifyDiscriptionService.addEventListener(FaultEvent.FAULT,onfault);
			modifyDiscriptionService.useProxy=false;
			
			switch(_type)
			{
				case 0:
					ID=(CaseSkeleton)(_point).getCID();
					modifyDiscriptionService.url = baseURL + "/modifyCaseDiscription.php?CID="+ID+"&discription="+_discription+"&type="+_type+"&rand="+Math.random();
					break;
				case 1:
					ID=(DataSourceSkeleton)(_point).getDID();
					modifyDiscriptionService.url = baseURL + "/modifyDataSourceDiscription.php?DID="+ID+"&discription="+_discription+"&type="+_type+"&rand="+Math.random();
					break;
				case 2:
					ID=(KnowledgeSkeleton)(_point).getKID();
					modifyDiscriptionService.url = baseURL + "/modifyKnowledgeDiscription.php?KID="+ID+"&discription="+_discription+"&type="+_type+"&rand="+Math.random();
					break;
				case 3:
					ID=(ConclusionSkeleton)(_point).getConID();
					modifyDiscriptionService.url = baseURL + "/modifyConclusionDiscription.php?ConID="+ID+"&discription="+_discription+"&type="+_type+"&rand="+Math.random();
					break;
			}
			modifyDiscriptionService.send();
		}
		//modify name async
		private function modifyNameAsync(evt:ResultEvent):void
		{
			if(evt.result.Result==null || evt.result.Result.ID ==null || evt.result.Result.type==null)
				return;
			
			var type:int = (int)(evt.result.Result.type);
			var ID:int = (int)(evt.result.Result.ID);
			var name:String = (String)(evt.result.Result.name);
			var point:PointSkeleton=null;
			switch(type)
			{
				case 0:
					point = getCaseFromCID(ID);
					break;
				case 1:
					point = getDataFromDID(ID);
					break;
				case 2:
					point = getKnowledgeFromKID(ID);
					break;
				case 3:
					point = getConclusionFromConID(ID);
					break;
			}
			
			point.setName(name);
			point.getSprite().invalidateDisplayList();
		}
		//modify dicription async
		private function modifyDiscriptionAsync(evt:ResultEvent):void
		{
			if(evt.result.Result == null  || evt.result.Result.ID == null || evt.result.Result.type ==null)
				return;
			
			var type:int = (int)(evt.result.Result.type);
			var ID:int = (int)(evt.result.Result.ID);
			var _discription:String = (String)(evt.result.Result.discription);
			var point:PointSkeleton=null;
			switch(type)
			{
				case 0:
					point = getCaseFromCID(ID);
					break;
				case 1:
					point = getDataFromDID(ID);
					break;
				case 2:
					point = getKnowledgeFromKID(ID);
					break;
				case 3:
					point = getConclusionFromConID(ID);
					break;
			}
			point.setDiscription(_discription);
			point.getSprite().invalidateDisplayList();
			
		}
		//Getter and Setter
		public function getDKRelationList():ArrayList
		{
			return DKRelationList;
		}

		public function setDKRelationList(value:ArrayList):void
		{
			DKRelationList = value;
		}

		public function getKConRelationList():ArrayList
		{
			return KConRelationList;
		}

		public function setKConRelationList(value:ArrayList):void
		{
			KConRelationList = value;
		}
		
		public function writeToXML():void
		{
			
			var xmlDoc:String=new String();
			//header
			
			//points

			var fp:FileReference = new FileReference();
			fp.addEventListener(Event.COMPLETE,onSelectComplete);
			fp.addEventListener(Event.CANCEL,onSelectCancel);
			fp.save("sdfsdfsa","aa");
		}
		
		private function onSelectComplete(evt:Event):void
		{
			
		}
		
		private function onSelectCancel(evt:Event):void{
			
		}
	}
}